package main

import (
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"time"
)

var bookmarks = map[string]string{
	"1": "google.com",
	"2": "bing.com",
	"3": "baidu.com",
}

func main() {
	// Default 使用 Logger 和 Recovery 中间件
	//engine := gin.Default()

	// 新建一个没有任何中间件的路由
	r := gin.New()

	// 全局中间件
	// Logger 中间件将日志写入 gin.DefaultWriter，即使你将 GIN_MODE 设置为 release。
	// By default gin.DefaultWriter = os.Stdout
	//r.Use(gin.Logger())
	r.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
		// 你的自定义格式
		return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
			param.ClientIP,
			param.TimeStamp.Format(time.RFC1123),
			param.Method,
			param.Path,
			param.Request.Proto,
			param.StatusCode,
			param.Latency,
			param.Request.UserAgent(),
			param.ErrorMessage,
		)
	}))

	// Recovery 中间件会 recover 任何 panic。如果有 panic 的话，会写入 500。
	r.Use(gin.Recovery())

	// 使用自定义的中间件
	r.GET("/bookmarks/:id", BookmarsMiddleware(), GoroutineMiddleware(), func(ctx *gin.Context) {
		log.Println("请求中...")
		bid := ctx.Param("id")
		if value, ok := bookmarks[bid]; ok {
			ctx.JSON(http.StatusOK, gin.H{"bookmarks": value})
		} else {
			ctx.String(http.StatusBadRequest, "something went wrong:%s",
				errors.New("there is no bookmarks"))
		}
	})

	r.Run(":8080")

}

// BookmarsMiddleware use my middleware
func BookmarsMiddleware() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		//var arr = make([]int, 0)
		// panic here
		//log.Println("this is a bookmars middleware:", arr[2])
		log.Println("前置中间件")
		ctx.Next()
		log.Println("后置中间件")

	}
}

// GoroutineMiddleware use copied context in goroutines
func GoroutineMiddleware() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		//c := ctx.Copy()
		go func() {
			// must copy context
			// 如果不使用也不会报错，以后再分析
			//time.Sleep(time.Second * 5)
			//c.JSON(http.StatusOK, gin.H{"message": "this from goroutines middleware"})
		}()
		ctx.Next()
	}
}
